package com.it.jasypt.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class SensitiveDataIdCardByRoleSerializer extends JsonSerializer<String> {

    public static String preciseMask(String value, char maskChar) {
        if (value == null) return null;

        int len = value.length();
        if (len == 0) return "";

        // 分段规则
        if (len == 1) {
            return String.valueOf(maskChar);
        } else if (len == 2) {
            return value.charAt(0) + String.valueOf(maskChar);
        } else if (len == 3) {
            return value.charAt(0) + String.valueOf(maskChar) + value.charAt(2);
        } else if (len <= 8) {
            return maskMiddle(value, 2, 2, maskChar);
        } else {
            return maskMiddle(value, 4, 4, maskChar);
        }
    }

    private static String maskMiddle(String value, int headKeep, int tailKeep, char maskChar) {
        String head = value.substring(0, headKeep);
        String tail = value.substring(value.length() - tailKeep);
        int maskLen = value.length() - headKeep - tailKeep;
        return head + IntStream.range(0, maskLen)
                .mapToObj(i -> String.valueOf(maskChar))
                .collect(Collectors.joining()) + tail;
    }

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }
        // 从上下文获取当前用户数据 ThreadLocal
        String[] mockRoles = {"role1", "role2", "role3", "role4", "role5", "role6", "role7", "role8", "owner"};
        String mockRole = mockRoles[new Random().nextInt(mockRoles.length)];

        if (mockRole.equals("owner")) {
            gen.writeString(value);
        } else {
            gen.writeString(preciseMask(value, '*'));
        }
    }
}